import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query, Req } from '@nestjs/common';
import { BaseController } from '../../base/base.controller';
import { LocaleService } from './locale.service';
import { DtoPipe } from '../../pipes/dto/dto.pipe';
import { AddDto, EditDto, PageDto } from './dto';
import { DbService } from '@app/db';
import { Locale } from '@app/db/common/entities/Locale';
import { Lang } from '@app/db/common/entities/Lang';
import { FindOptionsWhere, Like } from 'typeorm';

@Controller('locale')
export class LocaleController extends BaseController{
    constructor(
        private readonly service:LocaleService,
        private readonly db:DbService
    ) {
        super()
    }

    @Get()
    async locales() {
        return this.successRes(await this.db.locale.find({enable : true}, ['id', 'name', 'code']))
    }

    @Get('page')
    async page(@Query() dto:PageDto, @Req() { userId, isSuper }) {
        let result:PaginationResult<Locale> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<Locale> = {
            
        }

        if(dto.name) {
            where.name = Like('%' + dto.name +'%')
        }

        if(dto.code) {
            where.code = Like('%' + dto.code +'%')
        }

        result.total = await this.db.locale.count(where)

        if(result.total > 0) {
            result.rows = await this.db.locale.pagination(dto.pageNo, dto.pageSize, where, null, {sort : 'ASC', id : 'DESC'})
        }
        

        return this.successRes(result)

    }

    @Post('add')
    async add(@Body(new DtoPipe({skipMissingProperties : false})) dto:AddDto, @Req() { locale }) {
        if(true == await this.db.locale.isExistsByWhere({name : dto.name})) {
            return this.failRes(this.i18n.t(locale, 'nameIsExists'))
        }

        if(true == await this.db.locale.isExistsByWhere({code : dto.code})) {
            return this.failRes(this.i18n.t(locale, 'codeIsExists'))
        }

        dto.createTime = this.utils.time()

        const res = await this.db.locale.insert(dto)

        return res ? this.successRes(res.rows) : this.failRes()
    }


    @Put('edit/:id')
    async edit(@Body(new DtoPipe()) dto:EditDto, @Param('id', ParseIntPipe) id:number, @Req() { locale }) {
        if(id <= 0) return

        let fields = Object.keys(dto) as (keyof Locale)[]
        if(fields.length == 0) return this.successRes()

        const row = await this.db.locale.findOne({id : id}, fields)
        if(!row) return

        let updateData:KeyToValueType<Locale> = {}

        for(let k in row) {
            if(row[k] != dto[k]) {
                updateData[k] = dto[k]
            }
        }


        if(Object.keys(updateData).length == 0) return this.successRes()

        if(updateData.name && true == await this.db.locale.isExistsByWhere({name : updateData.name})) {
            return this.failRes(this.i18n.t(locale, 'nameIsExists'))
        }

        if(updateData.code && true == await this.db.locale.isExistsByWhere({code : updateData.code})) {
            return this.failRes(this.i18n.t(locale, 'codeIsExists'))
        }

        await this.db.locale.update({id : id}, updateData)
    }

    @Delete('delete/:id')
    async delete(@Param('id', ParseIntPipe) id:number) {
        if(id <= 0) return
        const res = await this.db.locale.delete({id : id})
        return res === 0 ? this.failRes() : this.successRes()
    }
}
